home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / sdi / helpers.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-08  |  9.3 KB  |  394 lines

  1. /*********************  helpers.c ************************************/
  2. #include "sdi.h"
  3. #include <sunwindow/notify.h>
  4. #include <fcntl.h>
  5. #include <sys/ioctl.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <suntool/textsw.h>
  9.  
  10. /*
  11.  * Copyright 1987 by Mark Weiser.
  12.  * Permission to reproduce and use in any manner whatsoever on Suns is granted
  13.  * so long as this copyright and other identifying marks of authorship
  14.  * in the code and the game remain intact and visible.  Use of this code
  15.  * in other products is reserved to me--I'm working on Mac and IBM versions.
  16.  */
  17.  
  18. /*
  19.  * This file contains routines providing help throughout sdi, although
  20.  * especially to the control panel.
  21.  */
  22.  
  23.  
  24. static short background_array[] = {
  25. #include "/usr/include/images/square_17.pr"
  26. };
  27. mpr_static(background_pr, 16, 16, 1, background_array);
  28.  
  29. void generic_slider_notify();
  30.  
  31. /* Used as an event_proc in panels to make an item read only */
  32. void
  33. no_events(item, event)
  34. Panel_item item;
  35. Event *event;
  36. {
  37. }
  38.  
  39. /* need functions, not macros, because of non-idempotent funcall arguments */
  40. max(x,y)
  41. {
  42.     return x<y ? y : x;
  43. }
  44.  
  45. min(x,y)
  46. {
  47.     return x<y ? x : y;
  48. }
  49.  
  50. /*
  51.  * Used to initiate the panel timer countdown associated with the
  52.  * '-t' option.
  53.  */
  54. start_timeout(item)
  55. Panel_item item;
  56. {
  57.     Notify_value timeout_proc();
  58.     struct itimerval timer;
  59.  
  60.     timer.it_interval.tv_usec = 0;
  61.     timer.it_interval.tv_sec = 1;
  62.     timer.it_value.tv_usec = 0;
  63.     timer.it_value.tv_sec = 1;
  64.     notify_set_itimer_func(item, timeout_proc, ITIMER_REAL, &timer, NULL);
  65. }
  66.  
  67. /*
  68.  * The proc that takes the timer notifications for the panel timer countdown
  69.  * associated with the '-t' option.  Started by proc 'start_timeout'.
  70.  */
  71. Notify_value
  72. timeout_proc(item, which)
  73. Panel_item item;
  74. int which;
  75. {
  76.     extern int continuous;
  77.     struct itimerval timer;
  78.     int val = (int)panel_get_value(item);
  79.     val -= 1;
  80.     if (running) panel_set_value(item, val);
  81.     if (val <= 0) {
  82.         continuous = 0;
  83.         end_proc();
  84.         continuous = 1;
  85.         panel_set_value(item, panel_get(item, PANEL_MAX_VALUE));
  86.         return;
  87.     }
  88. }
  89.  
  90. /*
  91.  * The remaining code in helper.c is concerned with different kinds
  92.  * of popups or pseudo-popups (for textsw's).  First a few local variables
  93.  */
  94. static Frame popup_frame = NULL;
  95. static Textsw popup_text;
  96. static Panel popup_panel;
  97. static Panel_item popup_msg_item;
  98. static void popup_yes_proc(), popup_no_proc(), popup_textsw_done();
  99.  
  100. /* 
  101.  * Pop a warning on the screen.  Return 1 if yes, 0 if no 
  102.  * Event is used to determine the x,y position of the popup, and Frame
  103.  * is the frame in which the event was received.
  104.  * Msg is a single-line string containing the message.  It should be
  105.  * in the form of a yes/no question, because it will be followed
  106.  * in the window by 'yes' and 'no' selection boxes.
  107.  */
  108. popup_warning(frame, event, msg)
  109. Frame *frame;
  110. Event *event;
  111. char *msg;
  112. {
  113.     int value;
  114.     init_popup_warn(frame, msg);
  115.     window_set(popup_frame, WIN_X, event_x(event),
  116.         WIN_Y, event_y(event),
  117.         0);
  118.     value = (int)window_loop(popup_frame);
  119.     window_set(popup_frame, FRAME_NO_CONFIRM, TRUE, 0);
  120.     window_destroy(popup_frame);
  121.     popup_frame = NULL;
  122.     return value;
  123. }
  124.  
  125. /*
  126.  * Pop up a message inside a textsw.  Since textsw's don't really
  127.  * popup (in SunOS 3.2), just display it and put up a 'done' button
  128.  * to kill it when the user is done.
  129.  * Frame should be the frame in which Event occured.  Msg can
  130.  * contain imbedded newlines.
  131.  */
  132. popup_msg(frame, event, msg)
  133. Frame *frame;
  134. Event *event;
  135. char *msg;
  136. {
  137.     int lines = count_lines(msg);
  138.     if (popup_frame != NULL) {
  139.         /* Can only do one of these at a time. */
  140.         return;
  141.     }
  142.     suspend_proc();
  143.     init_popup_msg(frame, msg, lines);
  144.     textsw_insert(popup_text, msg, strlen(msg));
  145.     window_set(popup_frame, WIN_X, event_x(event),
  146.         WIN_Y, event_y(event),
  147.         WIN_SHOW, TRUE,
  148.         0);
  149. }
  150.  
  151. /*
  152.  * A helper routine to do all the real work of setting up windows for warnings
  153.  */ 
  154. init_popup_warn(baseframe, msg)
  155. Frame baseframe;
  156. char *msg;
  157. {
  158.     popup_frame = window_create(baseframe, FRAME,
  159.         WIN_ERROR_MSG, "Can't create window.",
  160.         FRAME_DONE_PROC, popup_no_proc,
  161.         WIN_GRAB_ALL_INPUT, TRUE,
  162.         0);
  163.     popup_panel = window_create(popup_frame, PANEL,
  164.         WIN_ERROR_MSG, "Can't create window.",
  165.         PANEL_LAYOUT, PANEL_VERTICAL,
  166.         0);
  167.     popup_msg_item = panel_create_item(popup_panel, PANEL_MESSAGE,
  168.         0);
  169.     panel_create_item(popup_panel, PANEL_BUTTON,
  170.         PANEL_LABEL_IMAGE, panel_button_image(popup_panel, "Yes", 3, NULL),
  171.         PANEL_NOTIFY_PROC, popup_yes_proc,
  172.         PANEL_ITEM_Y, ATTR_ROW(1),
  173.         0);
  174.     panel_create_item(popup_panel, PANEL_BUTTON,
  175.         PANEL_LABEL_IMAGE, panel_button_image(popup_panel, "No", 2, NULL),
  176.         PANEL_NOTIFY_PROC, popup_no_proc,
  177.         PANEL_ITEM_Y, ATTR_ROW(1),
  178.         0);
  179.     panel_set(popup_msg_item, PANEL_LABEL_STRING, msg, 0);
  180.     window_fit(popup_panel);
  181.     window_fit(popup_frame);
  182. }
  183.  
  184. /*
  185.  * popup_yes_proc and popup_no_proc are helpers used for warning popups.
  186.  */
  187. static void
  188. popup_yes_proc(item, event)
  189. Panel_item item;
  190. Event *event;
  191. {
  192.     window_return(1);
  193. }
  194.  
  195. static void
  196. popup_no_proc(item, event)
  197. Panel_item item;
  198. Event *event;
  199. {
  200.     window_return(0);
  201. }
  202.  
  203. /*
  204.  * A helper proc to do all the work of window creation for message popups
  205.  */
  206. init_popup_msg(baseframe, msg, lines)
  207. Frame baseframe;
  208. char *msg;
  209. {
  210.     popup_frame = window_create(baseframe, FRAME,
  211.         WIN_ERROR_MSG, "Can't create window.",
  212.         FRAME_DONE_PROC, popup_textsw_done,
  213.         0);
  214.     popup_panel = window_create(popup_frame, PANEL,
  215.         /* WIN_BELOW, popup_text, */
  216.         WIN_X, ATTR_COL(0),        /* bug workaround, should not be necessary */
  217.         0);
  218.     panel_create_item(popup_panel, PANEL_BUTTON,
  219.         PANEL_LABEL_IMAGE, panel_button_image(popup_panel, "Done", 4, NULL),
  220.         PANEL_NOTIFY_PROC, popup_textsw_done,
  221.         0);
  222.     window_fit(popup_panel);
  223.     popup_text = window_create(popup_frame, TEXTSW,
  224.         WIN_ERROR_MSG, "Can't create window.",
  225.         WIN_ROWS, min(30, lines),
  226.         WIN_COLUMNS, max_line(msg)+3,
  227.         TEXTSW_IGNORE_LIMIT, TEXTSW_INFINITY,
  228.         TEXTSW_CONTENTS, msg,
  229.         TEXTSW_BROWSING, TRUE,
  230.         TEXTSW_DISABLE_LOAD, TRUE,
  231.         TEXTSW_DISABLE_CD, TRUE,
  232.         0);
  233.     window_fit(popup_frame);
  234. }
  235.  
  236. /* A helper for killing message popups. */
  237. static void
  238. popup_textsw_done()
  239. {
  240.     window_set(popup_frame, FRAME_NO_CONFIRM, TRUE, 0);
  241.     window_destroy(popup_frame);
  242.     popup_frame = NULL;
  243.     resume_proc();
  244. }
  245.  
  246. Menu
  247. null_menu_gen(m, operation)
  248. Menu m;
  249. Menu_generate operation;
  250. {
  251.     /*
  252.      * If I destroy the menu, then under very rapid buttoning on the
  253.      * border someone gets confused and passes me a bad menu descripter.
  254.      * menu_destroy(m);
  255.      */
  256.     m = menu_create(0);
  257.     return m;
  258. }
  259.  
  260. /*
  261.  * Fake an event, so anyone can popup a message. 
  262.  */
  263. easy_pop(msg)
  264. char *msg;
  265. {
  266.     Event event;
  267.     event_x(&event) = (int)window_get(controlframe, WIN_X); 
  268.     event_y(&event) = (int)window_get(controlframe, WIN_Y);
  269.     popup_msg(controlframe, &event, msg);
  270. }
  271.  
  272. easy_warn(msg)
  273. char *msg;
  274. {
  275.     Event event;
  276.     event_x(&event) = (int)window_get(controlframe, WIN_X); 
  277.     event_y(&event) = (int)window_get(controlframe, WIN_Y);
  278.     return popup_warning(controlframe, &event, msg);
  279. }
  280.  
  281. static Frame popup_panel_frame = 0;
  282. static int (*popup_panel_user_done_func)();
  283.  
  284. /*
  285.  * Helper for make_popup_panel, below.
  286.  */
  287. static
  288. popup_panel_done()
  289. {
  290.     if (popup_panel_user_done_func)
  291.         (*popup_panel_user_done_func)();
  292.     window_set(popup_panel_frame, FRAME_NO_CONFIRM, TRUE, 0);
  293.     window_destroy(popup_panel_frame);
  294.     popup_panel_frame = 0;
  295.     resume_proc();
  296. }
  297.  
  298. Panel
  299. make_popup_panel(panel_name, user_done_func)
  300. char *panel_name;
  301. int (*user_done_func)();
  302. {
  303.     extern struct pixfont *buttonfont; /* use 'struct pixfont' for 3.0 compatiblity */
  304.     Panel panel;
  305.     if (popup_panel_frame) {
  306.         /* don't permit nested calls. */
  307.         return NULL;
  308.     }
  309.     suspend_proc();
  310.     popup_panel_user_done_func = user_done_func;
  311.     popup_panel_frame = window_create(controlframe, FRAME,
  312.         FRAME_SHOW_LABEL, TRUE,
  313.         FRAME_DONE_PROC, popup_panel_done,
  314.         FRAME_LABEL, panel_name,
  315.         WIN_ERROR_MSG, "Can't create popup panel frame.",
  316.         0);
  317.     panel = window_create(popup_panel_frame, PANEL,
  318.         WIN_ERROR_MSG, "Can't create popup panel panel.",
  319.         PANEL_ITEM_X_GAP, 30,
  320.         PANEL_ITEM_Y_GAP, 15,
  321.         0);
  322.     (void) panel_create_item(panel, PANEL_BUTTON,
  323.         PANEL_LABEL_IMAGE, panel_button_image(panel, "Done", 6, buttonfont),
  324.         PANEL_NOTIFY_PROC, popup_panel_done,
  325.         0);
  326.     return panel;
  327. }
  328.  
  329. display_popup_panel(panel)
  330. Panel panel;
  331. {
  332.     if (panel == NULL || popup_panel_frame == NULL)
  333.         return;
  334.     window_fit(panel);
  335.     window_fit(popup_panel_frame);
  336.     window_set(popup_panel_frame, WIN_SHOW, TRUE, 0);
  337. }
  338.  
  339. start_next_round()
  340. {
  341.     extern void start_running_proc(), init_blast();
  342.     /* 
  343.      * Notice that things will break if blast_delay+1000
  344.      * is greater than 999,999.
  345.      */
  346.     panel_set(skill_item, PANEL_EVENT_PROC, (char *)no_events, 0);
  347.     clear_fields();
  348.     place_cities(citypw);
  349.     init_incoming();
  350.     update_cursor();
  351.     do_with_delay(start_running_proc, 0, blast_delay+1000);
  352.     do_with_delay(init_blast, 1, blast_delay);
  353. }
  354.  
  355. /*
  356.  * helper to delay the startup.
  357.  */
  358. void
  359. start_running_proc()
  360. {
  361.     running = 1;
  362. }
  363.  
  364. put_text(y, s)
  365. int y;
  366. char *s;
  367. {
  368.     struct pr_size size;
  369.     size = pf_textwidth(strlen(s), font, s);
  370.     pw_text(citypw, max_x / 2 - size.x / 2, max_y / 2 - 35 - (size.y/2)+ y, PIX_SRC, font, s);
  371.     pw_text(launchpw, max_x / 2 - size.x / 2, max_y / 2 - 35 - (size.y/2)+ y, PIX_SRC, font, s);
  372. }
  373.  
  374. draw_canvas_background(canvas)
  375. Canvas canvas;
  376. {
  377.     pw_replrop(window_get(canvas, CANVAS_PIXWIN), 0, 0, 
  378.         window_get(canvas, WIN_WIDTH), window_get(canvas, WIN_HEIGHT), 
  379.         PIX_SRC, &background_pr, 0, 0);
  380. }
  381.  
  382. draw_background()
  383. {
  384.     draw_canvas_background(citycanvas);
  385.     draw_canvas_background(launchcanvas);
  386. }
  387.  
  388. clear_fields()
  389. {
  390.     pw_writebackground(citypw, 0, 0, max_x, max_y, PIX_SRC);
  391.     pw_writebackground(launchpw, 0, 0, max_x, max_y+max_y
  392. , PIX_SRC);
  393. }
  394.